#!/usr/bin/env bash

# PACKAGE: Gunther
# VERSION: 2.0
# DATE: 09/30/08
# AUTHOR(S): Zarrar Shehzad

# Uses global arrays COMMANDS...etc
function commandLoop {
    local start=${1}
    local end=${2}
    
    # Set start
    if [[ -z "$start" ]]; then
        if [[ ! -z "${COMMANDS[0]}" ]]; then
            local start=0
        else
            local start=1
        fi
    fi
    # Set end
    if [[ -z "$end" ]]; then
        if [[ "$start" == 0 ]]; then
            end=$(( ${#COMMANDS[*]} - 1 ))
        else
            end=${#COMMANDS[*]}
        fi
    fi
    
    local i=0
    for (( i = ${start}; i <= $end; i++ )); do
        # Execute command (see include/command.sh)
        xfcExecute "${COMMANDS[$i]}" "${COMMANDS_INFO[$i]}" "${COMMANDS_INPUT[$i]}" "${COMMANDS_OUTPUT[$i]}" "${COMMANDS_EXT[$i]}" "${COMMANDS_EXTOPTIONS[$i]}"
        
        # Check return
        case "$?" in
            "$INPUT_ERROR" ) 
                return 1
                ;;
            "$OUTPUT_ERROR" ) 
                ;;
            0 )
                ;;
            * )
                return 1 # Nonzero exit of command
                ;;
        esac
    done
    
    return 0
}

# Internal default function to execute commands for following subLoop function...
# 1) actually this function just checks initial input and final output for a set of commands
# 2) then it just calls another function to execute the commands
function intLoop {
    local commandFile="$1"
    
    # Get commands (must get subjects first)
    # set by specific program file
    source "${commandFile}"

    # Check Input (see checks.sh)
    if [[ ! -z "$BIG_INPUT" ]]; then
        checkInput "$BIG_INPUT"
        inputError="$?"
    fi
    # Check Output (see checks.sh)
    if [[ "$to_skip" = 0 && ! -z "$BIG_OUTPUT" ]]; then
        checkOutput "$BIG_OUTPUT"
        outputError="$?"
    else
        zinfo "...skipping check of final output"
        outputError=0
    fi
    if [[ "$inputError" -ne 0 || "$outputError" -ne 0 ]]; then
        zerror "skipping subject $subject"
        skipSubject "$subject"
        return -1
    fi

    # Loop through commands
    commandLoop ${commandStart} ${commandEnd}
    if [[ "$?" -ne 0 ]]; then
        skipSubject "$subject"
        return -1
    fi
    
    echo
}

# Function to wrap around above internal function allowing for processing... of ROIs
mask=""
function maskLoop {
    local commandFile="$1"
    local masktype="$2"
    shift 2
    local masklist="$@"
    
    source "$GUNTHERDIR/include/masks.sh"
    
    # Process masks
    processMaskList "$masktype" "$masklist"
    
    for mask in ${masks[@]}; do
        # Check mask not empty
    	if [[ -z "$mask" ]]; then
    		continue
    	fi

        echo
        ztitle "Running ROI: ${mask}"
        
        # Get mask specific variables
        source "${gMaskConfigFile}"
        
        # Execute!
        intLoop "$commandFile"
    done
    
    return 0
}

# Create masks
mask=""
xCoord=""
yCoord=""
zCoord=""
function createMaskLoop {
    local commandFile="$1"
    local masktype="$2"
    shift 2
    local masklist="$@"
    
    source "$GUNTHERDIR/include/masks.sh"

    # Process masks
    processCreateMaskList "$masktype" "$masklist"
    
    # Loop through masks
    maskNum=${#masks[@]}
    local i=0
    for (( i = 0; i < ${maskNum}; i++ )); do
        ## Set vars
        mask="${masks[$i]}"
        xCoord="${xCoords[$i]}"
        yCoord="${yCoords[$i]}"
        zCoord="${zCoords[$i]}"
        
        echo
        ztitle "Creating ROI: ${mask}, x: ${xCoord}, y: ${yCoord}, z: ${zCoord}"
        
        # Get mask specific variables
        source "${gCreateMaskConfigFile}"
        
        # Execute!
        intLoop "$commandFile"
    done
    
    return 0
}



# Info:
#   Loops through a list of subjects to run a set of commands
# Usage:
#   subLoop <subject list TYPE> "<subject list>" "<config filename>" "<command filename>" "<another loop function name>" "<input for another loop function>"
# Options:
#   1) subject list TYPE: see processSubList in subjects.sh
#   2) subject list: see processSubList in subjects.sh
#   3) config: file with variables for subject paths, etc.
#   4) command: file with array of commands, etc.
#   5) loop: name of function to call within subject loop that will actually execute commands, e.g. can be another loop (OPTIONAL)
#   6..) loop variables: can be any number of variables that will be fed into loop defined previously (OPTIONAL)
# Return:
#   see xfcExecute in commands.sh
function subLoop {
    # User Variables
    local subtype="$1"
    local sublist="$2"
    local subConfigFile="$3"
    local commandFile="$4"
    local intFunction="$5"
    if [[ -z "$intFunction" ]]; then
        shift 4
        intFunction="intLoop"
    else
        shift 5
    fi
    local intVars="$@"
    
    # Function Variables
    local subject=""
    local numCommands=0
    
    # GET SUBJECTS
    # process list of subjects or list of files w/subjects
    # see subjects.sh
    procesSubList "$subtype" "$sublist"

    # PROCESS DATA
    # loop through subjects
    for subject in ${subjects[@]}; do

    	# Check subject not empty
    	if [[ -z "$subject" ]]; then
    		continue
    	fi

        echo
        ztitle "Running ${subject}"
        
        # Get subject specific variables
        # set in config/general.sh
        source "${subConfigFile}"
        
        # Execute!!!
        eval "${intFunction} ${commandFile} $@"
        
    done
    
    return 0
}